package com.java.thread;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

public class ThreadPoolExecutorTests {
    /**核心线程数,当通过池执行任务时，假如池中线程数小于CorePoolSize,每次执行任务都会创建新的任务*/
    static int corePoolSize=2;
    /**假如核心线程都在忙，再来新的任务，此时任务会存储到阻塞式任务队列*/
    static BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<>(1);
    /**当核心线程都在忙，任务队列也满了，再有新任务，此时要创建新线程*/
    static int maximumPoolSize=3;//这里包含核心线程数
    /**当没有那么多任务时，线程空闲了,可以在这个时间(keepAliveTime)之后释放一些临时线程*/
    static long keepAliveTime=60;
    /**时间单位*/
    static TimeUnit timeUnit=TimeUnit.SECONDS;
    /**创建线程的工厂*/
    static ThreadFactory threadFactory=new ThreadFactory() {
        //AtomicInteger对象可以以线程安全的方式产生自增、自减值。通过这个值可以给线程编号。
        private AtomicInteger atomicInteger=new AtomicInteger(1);
        private String threadNamePrefix="async-service-task-";
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r,threadNamePrefix+atomicInteger.getAndIncrement());
        }
    };
    /**当池无法处理这个任务时，要给出具体的拒绝策略(四种)*/
    static RejectedExecutionHandler handler=
            new ThreadPoolExecutor.AbortPolicy();//直接抛出异常
            // new ThreadPoolExecutor.CallerRunsPolicy();//由调用者线程执行
            // new ThreadPoolExecutor.DiscardPolicy();//直接丢弃任务;
            //new ThreadPoolExecutor.DiscardOldestPolicy();//丢弃队列中最老的任务。


    public static void main(String[] args) {
        //创建线程池
        ThreadPoolExecutor threadPoolExecutor=
        new ThreadPoolExecutor(corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                timeUnit,
                workQueue,
                handler);
        //执行任务
        threadPoolExecutor.execute(()->{//任务(Runnable)
            String tName=Thread.currentThread().getName();
            System.out.println(tName+"->execute task1");
            try{Thread.sleep(2000);}catch (Exception e){}
        });
        threadPoolExecutor.execute(()->{
            String tName=Thread.currentThread().getName();
            System.out.println(tName+"->execute task2");
            try{Thread.sleep(2000);}catch (Exception e){}
        });
        threadPoolExecutor.execute(()->{
            String tName=Thread.currentThread().getName();
            System.out.println(tName+"->execute task3");
            try{Thread.sleep(2000);}catch (Exception e){}
        });
        threadPoolExecutor.execute(()->{
            String tName=Thread.currentThread().getName();
            System.out.println(tName+"->execute task4");
            try{Thread.sleep(2000);}catch (Exception e){}
        });
        threadPoolExecutor.execute(()->{
            String tName=Thread.currentThread().getName();
            System.out.println(tName+"->execute task5");
            try{Thread.sleep(2000);}catch (Exception e){}
        });
        //threadPoolExecutor.submit(runnable)
        //threadPoolExecutor.submit(callable)

        //关闭线程池(不再接收新任务，等已有任务执行结束，关闭池)
        threadPoolExecutor.shutdown();
        //立刻关闭(不再接收新任务，也会尝试关闭正在执行的任务)
        //threadPoolExecutor.shutdownNow();
    }
}
